// #ifndef __tenacitas_distributed__call__h__
// #define __tenacitas_distributed__call__h__


// // =============================================================================
// /**
//    @file 
//    File description
// */


// // =============================================================================
// //                                 C++ Headers

// #include <ctime>
// #include <memory>

// // =============================================================================
// //                                 3rds Headers


// // =============================================================================
// //                                 Our Headers

// #include "call_recorder.h"

// // =============================================================================
// //                                 Namespaces
// using namespace std;


// // =============================================================================
// //                                 Macro Contants

// /**
//  */


// // =============================================================================
// //                                 Macro Commands

// /**
//  */


// /**
//    namespace of the organization
// */
// namespace tenacitas {
//     /**
//        namespace for the project
//     */
//     namespace distributed {

//         // =====================================================================
//         //                             Typedefs

//         /**
//          */


//         // =====================================================================
//         //                             Pre-Declarations


//         // =====================================================================
//         //                             Attributes

//         /**
//          */


//         // =====================================================================
//         //                             Functions

//         /**
//          */


//         // =====================================================================
//         //                             Classes

//         /** 

//             States of a call

//             +--> over
//             |
//             non-existing -> received ---+      |  +--> interrupted
//             |         |      |  |
//             |         |      |  |   +--> lost
//             |         |      |  |   |
//             |         +--> being_answered <--+    
//             |                               |
//             |                               |
//             +--> on_hold -------------------+

//             A call goes from 'non-existing' to 'received' when the network
//             receives a call.

//             A call goes from 'received' to 'being_answered' when an attendant
//             could be found to attend the call.

//             A call goes from 'being_answered' to 'over' when the client
//             normaly ceases the conversation with the attendant.

//             A call goes from 'being_answered' to 'interrupted' when the client
//             stops sending requests, without properly saying goodbye
//             (attendance timout).

//             A call goes from 'received' to 'on_hold' when no attendant could
//             be found to attend the call.

//             A call goes from 'on_hold' to 'being_answered' when an attendant
//             could be found to attend the call.

//             A call goes from 'being_answered' to 'lost' when the attendant
//             never receives any request from the client, i.e., the attendant
//             is assigned a call to attend, but the call is in silence.

            
//         */
//         template <typename t_recorder>
//         class call {

//             // -----------------------------------------------------------------
//             //    call - Friends

//         public:

//             // -----------------------------------------------------------------
//             //    call - Public Internal Types

//             typedef std::shared_ptr<call> ptr;

//             typedef t_recorder recorder_type;
            
//             /** Type of pointer for the @p logger */
//             typedef typename recorder_type::ptr recorder_ptr;
            

//             // -----------------------------------------------------------------
//             //    call - Public Constructors
            

//             call ( recorder_ptr p_recorder )
//                 : m_received( 0 ),
//                   m_trying_to_be_answered( 0 ),
//                   m_into_on_hold( 0 ),
//                   m_out_of_on_hold( 0 ),
//                   m_being_answered( 0 ),
//                   m_lost( 0 ),
//                   m_over( 0 ),
//                   m_interrupted( 0 ),
//                   m_recorder( p_recorder ) {}
            

//             call ( const call & p_call )
//                 : m_received( p_call.m_received ),
//                   m_trying_to_be_answered( p_call.m_trying_to_be_answered ),
//                   m_into_on_hold( p_call.m_into_on_hold ),
//                   m_out_of_on_hold( p_call.m_out_of_on_hold ),
//                   m_being_answered( p_call.m_being_answered ),
//                   m_lost( p_call.m_lost ),
//                   m_over( p_call.m_over ),
//                   m_interrupted( p_call.m_interrupted ),
//                   m_recorder( p_call.m_recorder ) {}
            
            
//             /**
//                Destructor
//             */
//             virtual ~call ( ) {}
            

//             // -----------------------------------------------------------------
//             //    call - Public Accessors

//             /** Informs when, if ever, this @p call object represents a call that
//                 was received */
//             bool received( time_t & p_when ) const {
//                 p_when = 0;
//                 if ( m_received != 0 ) {
//                     p_when = m_received;
//                 }
//                 return ( p_when != 0 );
//             }
            

//             /** Informs when, if ever, this @p call object represents a call that
//                 was put on-hold */
//             bool into_on_hold( time_t & p_when ) const {
//                 p_when = 0;
//                 if ( m_into_on_hold != 0 ) {
//                     p_when = m_into_on_hold;
//                 }
//                 return ( p_when != 0 );
//             }

//             /** Informs when, if ever, this @p call object started to be answered */
//             bool being_answered( time_t & p_when ) const {
//                 p_when = 0;
//                 if ( m_being_answered != 0 ) {
//                     p_when = m_being_answered;
//                 }
//                 return ( p_when != 0 );
//             }

//             /** Informs when, an attempt to answer the call was made  */
//             bool trying_to_answer( time_t & p_when ) const {
//                 p_when = 0;
//                 if ( m_trying_to_be_answered != 0 ) {
//                     p_when = m_trying_to_be_answered;
//                 }
//                 return ( p_when != 0 );
//             }

//             /** Informs when, if ever, this @p call object represents a call that
//                 was lost */
//             bool lost( time_t & p_when ) const {
//                 return true;
//             }

//             /** Informs when, if ever, this @p call object represents a call that
//                 was interrupted */
//             bool interrupted( time_t & p_when ) const {
//                 return true;
//             }

//             /** Informs when, if ever, this @p call object represents a call that
//                 was over */
//             bool over( time_t & p_when ) const {
//                 return true;
//             }
            

//             // -----------------------------------------------------------------
//             //    call - Public Helpers
            

//             // -----------------------------------------------------------------
//             //    call - Public Processors

//             /** States that the call was received */
//             void received( ){
//                 m_received = std::time( NULL );
//                 rec_info( m_recorder, "call received" );
//             }
            

//             /** States that an effort is being made to answer the call */
//             void trying_to_answer( ) {
//                 m_trying_to_be_answered = std::time( NULL );
//                 rec_info( m_recorder, "call trying to be anwsered" );
//             }
            

//             /** States that the call was put on-hold */
//             void into_on_hold( ) {
//                 m_into_on_hold = std::time( NULL );
//                 rec_info( m_recorder, "call into on-hold" );
//             }
            

//             /** States that the call was removed from on-hold */
//             void out_of_on_hold( ) {
//                 m_out_of_on_hold = std::time( NULL );
//                 rec_info( m_recorder, "call out of on-hold" );
//             }
            

//             /** States that the call started to be answered */
//             void being_answered( ) {
//                 m_being_answered = std::time( NULL );
//                 rec_info( m_recorder, "call being answered" );
//             }
            

//             /** States that the call was lost */
//             void lost( ) {
//                 m_lost = std::time( NULL );
//                 rec_info( m_recorder, "call lost" );
//             }
            

//             /** States that the call was interrupted */            
//             void interrupted( ) {
//                 m_interrupted = std::time( NULL );
//                 rec_info( m_recorder, "call interrupt" );
//             }
            

//             /** States that the call is over */            
//             void over( ) {
//                 m_over = std::time( NULL );
//                 rec_info( m_recorder, "call is over" );
//             }
            

//             // -----------------------------------------------------------------
//             //    call - Public Operators

//             /** Assignment */
//             call & operator = ( const call & p_call );
            

//             // -----------------------------------------------------------------
//             //    call - Public Attributes
            

//         private:

//             // -----------------------------------------------------------------
//             //    call - Private Internal Types


//             /** States of a call */
//             // typedef enum  { state_received = 0,
//             //                 state_trying_to_be_answered,
//             //                 state_on_hold,
//             //                 state_being_answered,
//             //                 state_lost,
//             //                 state_interrupted,
//             //                 state_over } state;
            
                

//             // -----------------------------------------------------------------
//             //    call - Private Constructors
            

//             // -----------------------------------------------------------------
//             //    call - Private Attributes

//             /** when the call was received */
//             time_t m_received;

//             /** when the call center tried to answer the call */
//             time_t m_trying_to_be_answered;

//             /** when, if ever, was the call put on hold */
//             time_t m_into_on_hold;

//             /** when, if ever, was the call out of on hold */
//             time_t m_out_of_on_hold;

//             /** when, if ever, the call started to be attended */
//             time_t m_being_answered;

//             /** when, if ever, the call was lost */
//             time_t m_lost;

//             /** when, if ever, was the call normaly over */
//             time_t m_over;

//             /** when, if ever, the call was interrupted */
//             time_t m_interrupted;

//             recorder_ptr m_recorder;
            

//         };

//     }
// }

// // =============================================================================
// //                     I M P L E M E N T A T I O N
// // =============================================================================

// using namespace tenacitas::distributed;


// #endif
